using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;

namespace HslControls
{
	/// <summary>
	/// 表格控件
	/// </summary>
	[Description("一个表格控件")]
	public class HslTable : UserControl
	{
		/// <summary>
		/// 绘制单元格的委托信息，可以自定义的实现一些高级的操作。
		/// </summary>
		/// <param name="g">绘图上下文</param>
		/// <param name="rowIndex">行号</param>
		/// <param name="colIndex">列号</param>
		/// <param name="rectangle">绘图的区域</param>
		/// <param name="value">本文内容</param>
		/// <param name="sf"></param>
		public delegate void DrawCellTextDelegate(Graphics g, int rowIndex, int colIndex, RectangleF rectangle, string value, StringFormat sf);

		private StringFormat sf = null;

		private Color borderColor = Color.LightGray;

		private Pen borderPen = new Pen(Color.LightGray);

		private Brush textBrush = new SolidBrush(Color.Gray);

		private Color headerColor = Color.DimGray;

		private Brush headerBrush = new SolidBrush(Color.DimGray);

		private Color topTextColor = Color.DarkSlateGray;

		private Brush topTextBrush = new SolidBrush(Color.DarkSlateGray);

		private float headTextSize = 18f;

		private float headHeight = 0.25f;

		private int rowsTotalCount = 5;

		private float[] columnWidth = new float[6]
		{
			0f,
			0.3f,
			0.45f,
			0.55f,
			0.8f,
			1f
		};

		private string[] columnHeader = new string[5]
		{
			"规格",
			"生产数量",
			"工艺",
			"完成度",
			"特别说明"
		};

		private string topHeaderText = "今日生产计划";

		private string assistHeaderText = "9月2日";

		private List<string[]> tableValues = new List<string[]>();

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		/// <summary>
		/// 获取或设置控件的背景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的背景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Transparent")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color BackColor
		{
			get
			{
				return base.BackColor;
			}
			set
			{
				base.BackColor = value;
			}
		}

		/// <summary>
		/// 获取或设置当前控件的文本
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前控件的文本")]
		[Category("HslControls")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		[Bindable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public override string Text
		{
			get
			{
				return base.Text;
			}
			set
			{
				base.Text = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置控件的前景色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的前景色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "Gray")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public override Color ForeColor
		{
			get
			{
				return base.ForeColor;
			}
			set
			{
				base.ForeColor = value;
				textBrush?.Dispose();
				textBrush = new SolidBrush(value);
			}
		}

		/// <summary>
		/// 获取或设置控件的表格边框的颜色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置控件的表格边框的颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "LightGray")]
		public Color BorderColor
		{
			get
			{
				return borderColor;
			}
			set
			{
				borderColor = value;
				borderPen?.Dispose();
				borderPen = new Pen(value);
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置当前的标题的文本颜色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前的标题的文本颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "DimGray")]
		public Color HeaderColor
		{
			get
			{
				return headerColor;
			}
			set
			{
				headerColor = value;
				headerBrush?.Dispose();
				headerBrush = new SolidBrush(value);
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置当前的最大标题的文本颜色
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前的最大标题的文本颜色")]
		[Category("HslControls")]
		[DefaultValue(typeof(Color), "DarkSlateGray")]
		public Color TopHeaderColor
		{
			get
			{
				return topTextColor;
			}
			set
			{
				topTextColor = value;
				topTextBrush?.Dispose();
				topTextBrush = new SolidBrush(value);
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置当前表格的数据行的行数，不包括顶部最大的标题行
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前表格的数据行的行数，不包括顶部最大的标题行")]
		[Category("HslControls")]
		[DefaultValue(5)]
		public int RowsTotalCount
		{
			get
			{
				return rowsTotalCount;
			}
			set
			{
				if (rowsTotalCount > 0)
				{
					rowsTotalCount = value;
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取或设置当前最大标题的文本信息，默认为今日生产计划
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前最大标题的文本信息，默认为今日生产计划")]
		[Category("HslControls")]
		[DefaultValue("今日生产计划")]
		public string TopHeaderText
		{
			get
			{
				return topHeaderText;
			}
			set
			{
				topHeaderText = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置当前辅助标题的文本信息，默认为9月2日
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前辅助标题的文本信息，默认为9月2日")]
		[Category("HslControls")]
		[DefaultValue("9月2日")]
		public string AssistHeaderText
		{
			get
			{
				return assistHeaderText;
			}
			set
			{
				assistHeaderText = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置当前最大标题的高度，如果小于1就是百分比，如果大于1就是绝对值
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置当前最大标题的高度，如果小于1就是百分比，如果大于1就是绝对值")]
		[Category("HslControls")]
		[DefaultValue(0.25f)]
		public float TopHeaderHeight
		{
			get
			{
				return headHeight;
			}
			set
			{
				headHeight = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 列的宽度信息设置，数组的长度决定了列的数量
		/// </summary>
		[Category("HslControls")]
		[Description("列的宽度信息设置，数组的长度决定了列的数量")]
		[TypeConverter(typeof(CollectionConverter))]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public float[] ColumnWidth
		{
			get
			{
				return columnWidth;
			}
			set
			{
				columnWidth = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 列的标题信息设置，数组长度应该刚好是列的数组，如果少于，多出来的列则为空，如果大于，多出来的列则不显示
		/// </summary>
		[Category("HslControls")]
		[Description("列的标题信息设置，数组长度应该刚好是列的数组，如果少于，多出来的列则为空，如果大于，多出来的列则不显示")]
		[TypeConverter(typeof(CollectionConverter))]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
		public string[] ColumnHeader
		{
			get
			{
				return columnHeader;
			}
			set
			{
				columnHeader = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置顶部标题的字体大小，默认18
		/// </summary>
		[Browsable(true)]
		[Description("获取或设置顶部标题的字体大小，默认18")]
		[Category("HslControls")]
		[DefaultValue(28f)]
		public float TopHeaderTextSize
		{
			get
			{
				return headTextSize;
			}
			set
			{
				headTextSize = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 当绘制单元格的时候触发
		/// </summary>
		public event DrawCellTextDelegate OnDrawCellTextEvent;

		/// <summary>
		/// 实例化一个表格对象
		/// </summary>
		public HslTable()
		{
			InitializeComponent();
			sf = new StringFormat();
			sf.Alignment = StringAlignment.Center;
			sf.LineAlignment = StringAlignment.Center;
			SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
			SetStyle(ControlStyles.ResizeRedraw, value: true);
			SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
			if (GetService(typeof(IDesignerHost)) != null || LicenseManager.UsageMode == LicenseUsageMode.Designtime)
			{
				tableValues.Add(new string[5]
				{
					"φ31-61-2.5",
					"1000",
					"A类型",
					"800 nm",
					""
				});
			}
		}

		/// <inheritdoc />
		protected override void OnPaint(PaintEventArgs e)
		{
			base.OnPaint(e);
			e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			if (base.Width >= 20 && base.Height >= 20)
			{
				PaintHslControls(e.Graphics, base.Width, base.Height);
			}
		}

		/// <summary>
		/// 可以在任意的画刷上绘制当前的控件的图形
		/// </summary>
		/// <param name="g">画刷</param>
		/// <param name="width">宽度信息</param>
		/// <param name="height">高度信息</param>
		public void PaintHslControls(Graphics g, float width, float height)
		{
			if (!Authorization.iashdiadasbdnajsdhjaf())
			{
				return;
			}
			float rowHeadHeight = (headHeight < 1f) ? (height * headHeight) : headHeight;
			float rowTableHeight = (rowsTotalCount == 0) ? (height - rowHeadHeight) : ((height - rowHeadHeight) / (float)rowsTotalCount);
			if (headHeight > 0f)
			{
				RectangleF rectangle2 = new RectangleF(0f, 0f, width, rowHeadHeight);
				using Font font = new Font(Font.FontFamily, headTextSize);
				g.DrawString(topHeaderText, font, topTextBrush, rectangle2, sf);
				g.DrawString(point: new PointF(width * 0.5f + g.MeasureString(topHeaderText, font).Width / 2f, rectangle2.Height / 2f + (float)font.Height / 2f - (float)Font.Height - 1f), s: assistHeaderText, font: Font, brush: topTextBrush);
			}
			for (int l = 0; l < columnHeader.Length; l++)
			{
				if (l + 1 < columnWidth.Length)
				{
					g.DrawString(layoutRectangle: new RectangleF(width * columnWidth[l], rowHeadHeight, width * (columnWidth[l + 1] - columnWidth[l]), rowTableHeight), s: columnHeader[l], font: Font, brush: headerBrush, format: sf);
				}
			}
			g.DrawLine(borderPen, 0f, 0f, width - 1f, 0f);
			if (headHeight > 0f)
			{
				g.DrawLine(borderPen, 0f, (int)rowHeadHeight, width - 1f, (int)rowHeadHeight);
			}
			for (int k = 1; k <= rowsTotalCount; k++)
			{
				g.DrawLine(borderPen, 0f, (int)((float)k * rowTableHeight + rowHeadHeight), width - 1f, (int)((float)k * rowTableHeight + rowHeadHeight));
			}
			g.DrawLine(borderPen, 0f, height - 1f, width - 1f, height - 1f);
			g.DrawLine(borderPen, 0f, 0f, 0f, height - 1f);
			g.DrawLine(borderPen, width - 1f, 0f, width - 1f, height - 1f);
			for (int j = 0; j < columnWidth.Length; j++)
			{
				g.DrawLine(borderPen, (int)(width * columnWidth[j]), (int)rowHeadHeight, (int)(width * columnWidth[j]), height - 1f);
			}
			for (int rowIndex = 0; rowIndex < tableValues.Count; rowIndex++)
			{
				for (int i = 0; i < columnHeader.Length; i++)
				{
					if (i + 1 < columnWidth.Length)
					{
						RectangleF rectangle = new RectangleF(width * columnWidth[i], rowTableHeight * (float)(rowIndex + 1) + rowHeadHeight, width * (columnWidth[i + 1] - columnWidth[i]) - 1f, rowTableHeight - 1f);
						if (this.OnDrawCellTextEvent == null)
						{
							DrawCellText(g, rowIndex, i, rectangle, tableValues[rowIndex][i], sf);
						}
						else
						{
							this.OnDrawCellTextEvent(g, rowIndex, i, rectangle, tableValues[rowIndex][i], sf);
						}
					}
				}
			}
		}

		/// <summary>
		/// 绘制单元格是核心方法，你也可以根据自己的需求进行重写，实现一些特殊的图形或是颜色显示
		/// </summary>
		/// <param name="g">绘图上下文</param>
		/// <param name="rowIndex">行索引</param>
		/// <param name="colIndex">列索引</param>
		/// <param name="rectangle">文本的区域</param>
		/// <param name="value">文本的值</param>
		/// <param name="sf">文本的对齐方式</param>
		public virtual void DrawCellText(Graphics g, int rowIndex, int colIndex, RectangleF rectangle, string value, StringFormat sf)
		{
			g.DrawString(value, Font, textBrush, rectangle, sf);
		}

		/// <summary>
		/// 从底部新增一条数据信息
		/// </summary>
		/// <param name="values">数据信息</param>
		public void AddRowDown(string[] values)
		{
			AddRowDown(new List<string[]>
			{
				values
			});
		}

		/// <summary>
		/// 从底部新增多条数据信息
		/// </summary>
		/// <param name="values">数据信息</param>
		public void AddRowDown(List<string[]> values)
		{
			tableValues.AddRange(values);
			while (tableValues.Count >= rowsTotalCount)
			{
				tableValues.RemoveAt(0);
			}
			Invalidate();
		}

		/// <summary>
		/// 从顶部新增一条数据信息
		/// </summary>
		/// <param name="values">数据信息</param>
		public void AddRowTop(string[] values)
		{
			AddRowTop(new List<string[]>
			{
				values
			});
		}

		/// <summary>
		/// 从顶部新增一条数据信息
		/// </summary>
		/// <param name="values">数据信息</param>
		public void AddRowTop(List<string[]> values)
		{
			if (values != null)
			{
				for (int i = 0; i < values.Count; i++)
				{
					tableValues.Insert(0, values[i]);
				}
			}
			while (tableValues.Count >= rowsTotalCount)
			{
				tableValues.RemoveAt(tableValues.Count - 1);
			}
			Invalidate();
		}

		/// <summary>
		/// 设置表的所有的数据信息
		/// </summary>
		/// <param name="values">数据值</param>
		public void SetTableValue(List<string[]> values)
		{
			tableValues = values;
			Invalidate();
		}

		/// <summary>
		/// 设置当前的表格的指定单元的数据内容，需要传递单元格信息，数据值，是否刷新界面。
		/// </summary>
		/// <param name="rowIndex">所在的行号信息</param>
		/// <param name="colIndex">所在的列号信息</param>
		/// <param name="value">数据值</param>
		/// <param name="updateUI">是否刷新界面</param>
		public void SetTableValue(int rowIndex, int colIndex, string value, bool updateUI = true)
		{
			if (rowIndex < tableValues.Count && colIndex < tableValues[rowIndex].Length)
			{
				tableValues[rowIndex][colIndex] = value;
				if (updateUI)
				{
					Invalidate();
				}
			}
		}

		/// <summary>
		/// 获取指定行号，列号的单元格的文本信息，如果索引超出，返回NULL
		/// </summary>
		/// <param name="rowIndex">行号信息</param>
		/// <param name="colIndex">列号信息</param>
		/// <returns>单元格文本信息</returns>
		public string GetTableValue(int rowIndex, int colIndex)
		{
			if (rowIndex >= tableValues.Count)
			{
				return null;
			}
			if (colIndex >= tableValues[rowIndex].Length)
			{
				return null;
			}
			return tableValues[rowIndex][colIndex];
		}

		/// <summary>
		/// 获取所有的数据信息
		/// </summary>
		/// <returns>单元格文本信息</returns>
		public List<string[]> GetTableValue()
		{
			return tableValues;
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			SuspendLayout();
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			BackColor = System.Drawing.Color.White;
			Font = new System.Drawing.Font("微软雅黑", 9f, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, 134);
			ForeColor = System.Drawing.Color.Gray;
			base.Name = "HslTable";
			base.Size = new System.Drawing.Size(444, 206);
			ResumeLayout(false);
		}
	}
}
